﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KylinORM.Utils;

namespace KylinORM.Aspect
{
    /// <summary>
    /// 实体类型默认的连接方式
    /// </summary>
    public class EJoinMethod : ICloneable<EJoinMethod>
    {
        private string template = "";
        private EJoinMethod(string template)
        {
            this.template = template;
        }
        /// <summary>
        /// 返回表示当前 System.Object 的 System.String
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.template;
        }
        /// <summary>
        /// 返回该字符串的哈希代码
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.ToString().GetHashCode();
        }
        /// <summary>
        /// 确定指定的 System.Object 是否等于当前的 System.Object
        /// </summary>
        /// <param name="obj">与当前的 System.Object 进行比较的 System.Object</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return this.GetHashCode() == obj.GetHashCode();
        }

        /// <summary>
        /// 不使用连接
        /// </summary>
        public static EJoinMethod None = new EJoinMethod("{0}");
        /// <summary>
        /// 内连接
        /// </summary>
        public static EJoinMethod InnerJoin = new EJoinMethod("{0} inner join {1}");
        /// <summary>
        /// 左连接
        /// </summary>
        public static EJoinMethod LeftJoin = new EJoinMethod("{0} left join {1}");
        /// <summary>
        /// 右连接
        /// </summary>
        public static EJoinMethod RightJoin = new EJoinMethod("{0} right join {1}");
        /// <summary>
        /// 全连接
        /// </summary>
        public static EJoinMethod FullJoin = new EJoinMethod("{0} full join {1}");
        /// <summary>
        /// 交叉连接
        /// </summary>
        public static EJoinMethod CrossJoin = new EJoinMethod("{0} cross join {1}");



        /// <summary>
        /// 使用自定义连接条件
        /// </summary>
        /// <param name="template">连接模板，{0}代表实体名称 {1}代表连接目标和方式</param>
        /// <returns></returns>
        /// <example>以下语句将被翻译为[TableName] outer join [Target]
        /// <code>{0} outer join {1}</code>
        /// </example>
        public static EJoinMethod CustomMethod(string template)
        {
            return new EJoinMethod(template);
        }

        EJoinMethod ICloneable<EJoinMethod>.Clone()
        {
            return new EJoinMethod(this.template);
        }

        object ICloneable.Clone()
        {
            return ((ICloneable<EJoinMethod>)this).Clone();
        }



        /// <summary>
        /// 默认连接方式到自定义连接方式的映射
        /// </summary>
        private static Dictionary<EJoinMethodBase, EJoinMethod> joinMethodMap = new Dictionary<EJoinMethodBase, EJoinMethod>
        {
            { EJoinMethodBase.None, EJoinMethod.None },
            { EJoinMethodBase.InnerJoin, EJoinMethod.InnerJoin },
            { EJoinMethodBase.LeftJoin, EJoinMethod.LeftJoin },
            { EJoinMethodBase.RightJoin, EJoinMethod.RightJoin },
            { EJoinMethodBase.FullJoin, EJoinMethod.FullJoin },
            { EJoinMethodBase.CrossJoin, EJoinMethod.CrossJoin },
            { EJoinMethodBase.CustomMethod, EJoinMethod.CustomMethod("") }
        };
        
        /// <summary>
        /// 将默认连接方式转换为自定义连接方式
        /// </summary>
        /// <param name="joinMethod"></param>
        /// <returns></returns>
        public static implicit operator EJoinMethod(EJoinMethodBase joinMethod)
        {
            return joinMethodMap[joinMethod];
        }
    }
}
